package Common

import (
	"encoding/json"
	"log"
	"web_back_go/DAO/gorm"
	"web_back_go/DAO/gorm/GormModel"
	"web_back_go/Dto"
	"web_back_go/Util"
)

/*
CalculateTransfee
  - @Description: 计算运费
*/
func CalculateTransfee(productItem Dto.ShopCartItemDto, userAddr GormModel.TzUserAddr) float64 {
	var product GormModel.TzProd
	db := gorm.Db
	db.Where("prod_id = ?", productItem.ProdId).First(&product)
	cityId := userAddr.CityID
	var deliveryModeVO Dto.DeliveryMode

	if product.DeliveryMode.Valid { // 先检查 Valid
		err := json.Unmarshal([]byte(product.DeliveryMode.String), &deliveryModeVO)
		if err != nil {
			log.Println("Failed to decode DeliveryMode:", err)
			panic(err)
		}
	} else {
		log.Println("DeliveryMode is nil or invalid")
	}
	// 没有店铺配送的方式
	if !deliveryModeVO.HasShopDelivery {
		return 0.0
	}
	if product.DeliveryTemplateID == nil {
		return 0.0
	}
	//找出该产品的运费项
	transport := GetTransportAndAllItems(*product.DeliveryTemplateID)
	//商家把运费模板删除
	if transport == nil {
		return 0.0
	}
	sku := GormModel.TzSku{}
	db.Where("sku_id =?", productItem.SkuId).First(&sku)
	// 用于计算运费的件数
	piece := getPiece(productItem, transport, sku)
	//如果有包邮的条件
	if transport.HasFreeCondition == 1 {
		// 获取所有的包邮条件
		transfeeFrees := transport.TransfeeFrees
		for _, transfeeFree := range transfeeFrees {
			freeCityList := transfeeFree.TranscityFrees
			for _, freeCity := range freeCityList {
				if freeCity.TzArea.AreaID != int64(cityId) {
					continue
				}
				//包邮方式 （0 满x件/重量/体积包邮 1满金额包邮 2满x件/重量/体积且满金额包邮）
				isFree := (transfeeFree.FreeType == 0 && piece >= transfeeFree.Piece) ||
					(transfeeFree.FreeType == 1 && productItem.ProductTotalAmount >= transfeeFree.Amount) ||
					(transfeeFree.FreeType == 2 && piece >= transfeeFree.Piece && productItem.ProductTotalAmount >= transfeeFree.Amount)
				if isFree {
					return 0.0
				}
			}
		}
	}

	//订单的运费项
	var transfee *GormModel.TzTransfee
	transfees := transport.Transfees
	for _, dbTransfee := range transfees {
		// 将该商品的运费设置为默认运费
		if transfee == nil && Util.SliceIsEmpty(dbTransfee.Transcities) {
			transfee = &dbTransfee
		}
		// 如果在运费模板中的城市找到该商品的运费，则将该商品由默认运费设置为该城市的运费
		for _, area := range dbTransfee.Transcities {
			if area.TzArea.AreaID == int64(cityId) {
				transfee = &dbTransfee
				break
			}
		}
		// 如果在运费模板中的城市找到该商品的运费，则退出整个循环
		if transfee != nil && Util.SliceIsEmpty(transfee.Transcities) {
			break
		}
	}
	// 如果无法获取到任何运费相关信息，则返回0运费
	if transfee == nil {
		return 0.0
	}
	// 产品的运费
	fee := transfee.FirstFee
	// 如果件数大于首件数量，则开始计算超出的运费
	if piece > transfee.FirstPiece {
		// 续件数量
		prodContinuousPiece := piece - transfee.FirstPiece
		// 续件数量的倍数，向上取整
		mulNumber := int(prodContinuousPiece / transfee.ContinuousPiece)
		// 续件数量运费
		continuousFee := transfee.ContinuousFee * float64(mulNumber)
		fee = fee + continuousFee
	}
	return fee
}

/*
GetTransportAndAllItems
  - @Description: 获取运费项和所有的产品项
  - @param transportId
  - @return *GormModel.TzTransport
*/
func GetTransportAndAllItems(transportId int64) *GormModel.TzTransport {
	var transport *GormModel.TzTransport
	db := gorm.Db
	db.Raw(`
		   select feefree.*,cityfree.*,ta.* from tz_transfee_free feefree 
    left join tz_transcity_free cityfree on feefree.transfee_free_id = cityfree.transfee_free_id
    left join tz_area ta on cityfree.free_city_id = ta.area_id
    where feefree.transport_id = ? order by feefree.transfee_free_id`, transportId).Scan(&transport)
	if transport == nil {
		return nil
	}
	var transfeeFrees *[]GormModel.TzTransfeeFree
	db.Raw(` select feefree.*,cityfree.*,ta.* from tz_transfee_free feefree 
    left join tz_transcity_free cityfree on feefree.transfee_free_id = cityfree.transfee_free_id
    left join tz_area ta on cityfree.free_city_id = ta.area_id
    where feefree.transport_id = ? order by feefree.transfee_free_id`, transportId).Scan(&transfeeFrees)
	transport.TransfeeFrees = *transfeeFrees
	return transport
}

/*
  - 0全部商品参与

COUNT(0),

  - 1指定商品参与

WEIGHT(1),

  - 2指定商品不参与

VOLUME(2)
;
*/
func getPiece(productItem Dto.ShopCartItemDto, transport *GormModel.TzTransport, sku GormModel.TzSku) float64 {
	piece := 0.0
	if transport.ChargeType == 0 {
		// 按件数计算运费
		piece = float64(productItem.ProdCount)
	} else if transport.ChargeType == 1 {
		// 按重量计算运费
		weight := 0.0
		if sku.Weight == nil {
			piece = 0.0
		} else {
			weight = *sku.Weight
		}
		piece = weight * float64(productItem.ProdCount)
	} else if transport.ChargeType == 2 {
		// 按体积计算运费
		volume := 0.0
		if sku.Volume == nil {
			volume = 0.0
		} else {
			volume = *sku.Volume
		}
		piece = volume * float64(productItem.ProdCount)
	}
	return piece
}
